#ifndef VECTOR3_H
#define VECTOR3_H

namespace Cvekas {

/// 3D Vector
struct Vector3 : public D3DXVECTOR3 
{
public:
	Vector3();
	Vector3(const float* f);
	Vector3(const D3DXFLOAT16* f);
	Vector3(float x, float y, float z);
	Vector3(const D3DXVECTOR3& v);

	operator D3DXVECTOR3&();
	operator const D3DXVECTOR3&() const;

	void set( float vx, float vy, float vz );
	float length() const;
	float lengthSq() const;
	float dot( const Vector3& v ) const;
	void normalize();

	Vector3 cross( const Vector3& v ) const;
	Vector3 getNormalized() const;
};

inline Vector3::Vector3() 
	: 
D3DXVECTOR3() 
{}

inline Vector3::Vector3(const float* f) 
	: 
D3DXVECTOR3(f) 
{}

inline Vector3::Vector3(const D3DXFLOAT16* f)
	:
D3DXVECTOR3(f) 
{}

inline Vector3::Vector3(float vx, float vy, float vz) 
	:
D3DXVECTOR3(vx, vy, vz) 
{}

inline Vector3::Vector3(const D3DXVECTOR3& v)
	:
D3DXVECTOR3(v) 
{}

inline void Vector3::set(float vx, float vy, float vz) 
{ 
	x = vx; 
	y = vy; 
	z = vz; 
}

inline float Vector3::length() const 
{ 
	return D3DXVec3Length(this); 
}

inline float Vector3::lengthSq() const 
{ 
	return D3DXVec3LengthSq(this); 
}

inline float Vector3::dot(const Vector3& v) const 
{ 
	return D3DXVec3Dot(this, &v); 
}

inline Vector3 Vector3::cross(const Vector3& v) const 
{
	Vector3 res;
	res.x = y * v.z - z * v.y;
	res.y = z * v.x - x * v.z;
	res.z = x * v.y - y * v.x;
	return res;
}

inline void Vector3::normalize() 
{
	D3DXVec3Normalize(this, this);
}

inline Vector3 Vector3::getNormalized() const 
{
	Vector3 v;
	D3DXVec3Normalize( &v, this );
	return v;
}

inline Vector3::operator D3DXVECTOR3&() 
{ 
	return *this; 
}

inline Vector3::operator const D3DXVECTOR3&() const 
{ 
	return *this; 
}

} // namespace

#endif